import os
import io
import os
import subprocess

from PIL import Image

from common.comm_utils import get_file_name
from common.cache import media_cache


def save_media_content(media_type: str, content: bytes, description: str = None, media_id: str = None,
                       content_type: str = None) -> str:
    """统一的媒体文件保存函数

    Args:
        media_type (str): 媒体类型 ('image', 'audio', 'video')
        content (bytes): 文件内容
        description (str, optional): 描述信息，用于生成文件名
        media_id (str, optional): 媒体ID，用于缓存和文件名生成
        content_type (str, optional): 内容类型，用于确定文件扩展名

    Returns:
        str: 可访问的URL路径
    """
    try:
        # 确定保存目录
        type_dirs = {
            'image': 'ai_images',
            'audio': 'ai_voices',
            'video': 'ai_videos'
        }

        if media_type not in type_dirs:
            raise ValueError(f"不支持的媒体类型: {media_type}")

        save_dir = f'lucky_web/public/ai_material/{type_dirs[media_type]}'
        os.makedirs(save_dir, exist_ok=True)

        # 从content_type确定文件扩展名
        ext = None
        if content_type:
            if 'jpeg' in content_type or 'jpg' in content_type:
                ext = '.jpg'
            elif 'png' in content_type:
                ext = '.png'
            elif 'mp4' in content_type:
                ext = '.mp4'
            elif 'mp3' in content_type:
                ext = '.mp3'
            elif 'wav' in content_type:
                ext = '.wav'

        # 如果无法从content_type确定，使用默认扩展名
        if not ext:
            default_exts = {
                'image': '.jpg',
                'audio': '.mp3',
                'video': '.mp4'
            }
            ext = default_exts[media_type]

        # 改进文件名生成逻辑
        try:
            file_name = get_file_name(description if description else media_id)
        except Exception as e:
            print(f"文件名生成失败: {str(e)}, 使用时间戳作为文件名")
            # 使用时间戳作为备选文件名
            from datetime import datetime
            file_name = datetime.now().strftime("%Y%m%d_%H%M%S")
        
        # 确保文件名不为空
        if not file_name:
            from datetime import datetime
            file_name = datetime.now().strftime("%Y%m%d_%H%M%S")

        # 添加扩展名
        if not file_name.endswith(ext):
            file_name += ext

        file_path = os.path.join(save_dir, file_name)

        # 检查缓存
        if media_id and media_cache.get(media_id):
            cached_path = media_cache.get(media_id)
            if os.path.exists(cached_path):
                print(f"媒体文件已存在: {cached_path}")
                return f"https://luckyzhou.online/ai_material/{type_dirs[media_type]}/{os.path.basename(cached_path)}"

        # 根据媒体类型处理文件内容
        if media_type == 'image':
            image = Image.open(io.BytesIO(content))
            image.save(file_path, quality=95, optimize=True)
        elif media_type == 'video':
            # 确保ffmpeg可用
            try:
                subprocess.run(['ffmpeg', '-version'], capture_output=True, check=True)
            except (subprocess.SubprocessError, FileNotFoundError):
                # 如果ffmpeg不可用，直接保存原始文件
                print("警告: ffmpeg不可用，将直接保存原始视频文件")
                with open(file_path, 'wb') as f:
                    f.write(content)
            else:
                # ffmpeg可用，进行视频处理
                temp_path = file_path + '.temp'
                try:
                    # 保存临时文件
                    with open(temp_path, 'wb') as f:
                        f.write(content)

                    # 使用ffmpeg优化视频
                    result = subprocess.run([
                        'ffmpeg',
                        '-i', temp_path,
                        '-c', 'copy',
                        file_path
                    ], capture_output=True, text=True)

                    if result.returncode != 0:
                        print(f"ffmpeg处理失败: {result.stderr}")
                        # 如果ffmpeg处理失败，使用原始文件
                        os.rename(temp_path, file_path)
                finally:
                    # 清理临时文件
                    if os.path.exists(temp_path):
                        try:
                            os.remove(temp_path)
                        except OSError as e:
                            print(f"清理临时文件失败: {e}")
        else:
            # 直接写入文件
            with open(file_path, 'wb') as f:
                f.write(content)

        # 缓存media_id和文件路径
        if media_id:
            media_cache.add(media_id, file_path)

        # 记录文件大小
        original_size = len(content)
        saved_size = os.path.getsize(file_path)
        print(f"文件 {file_name} 保存完成:")
        print(f"原始大小: {original_size / 1024:.2f}KB")
        print(f"保存大小: {saved_size / 1024:.2f}KB")

        return f"https://luckyzhou.online/ai_material/{type_dirs[media_type]}/{file_name}"

    except Exception as e:
        print(f"保存媒体文件失败: {str(e)}")
        # 添加更详细的错误信息
        import traceback
        print(f"详细错误信息: {traceback.format_exc()}")
        raise